using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using System.Text;

namespace NEX_Datos
{
    public class Transaccion : IDisposable
    {

        #region Campos

        private Boolean fTransaccional;
        private MySqlCommand fSqlCommand;

        #endregion

        #region Constructores

        public Transaccion()
        {
            this.fTransaccional = true;
        }

        public Transaccion(Boolean transaccional)
        {
            this.fTransaccional = transaccional;
        }

        #endregion

        #region Metodos Privados

        private Boolean Transaccional()
        {
            return this.fTransaccional;
        }

        private void EventoAntesDelCommit()
        {
            if (this.AntesDelCommit != null)
            {
                this.AntesDelCommit();
            }
            this.AntesDelCommit = null;
        }

        private void EventoDespuesDelCommit()
        {
            if (this.DespuesDelCommit != null)
            {
                this.DespuesDelCommit();
            }
            this.DespuesDelCommit = null;
        }

        private void EventoAntesDelRollback()
        {
            if (this.AntesDelRollback != null)
            {
                this.AntesDelRollback();
            }
            this.AntesDelRollback = null;
        }

        private void EventoDespuesDelRollback()
        {
            if (this.DespuesDelRollback != null)
            {
                this.DespuesDelRollback();
            }
            this.DespuesDelRollback = null;
        }

        #endregion

        #region Metodos Protegidos

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.fSqlCommand.Dispose();
            }
        }

        #endregion

        #region Metodos Internos

        public MySqlCommand SqlCommandObtener()
        {
            if (this.fSqlCommand == null)
            {
                this.fSqlCommand = UtilidadAD.CreateSqlCommand();
                if (this.Transaccional())
                {
                    this.fSqlCommand.Transaction = this.fSqlCommand.Connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
                }
            }
            this.fSqlCommand.Parameters.Clear();
            return this.fSqlCommand;
        }

        #endregion

        #region Metodos Publicos

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Commit()
        {
            this.EventoAntesDelCommit();
            if (this.fSqlCommand != null)
            {
                if (this.Transaccional())
                {
                    this.fSqlCommand.Transaction.Commit();
                    this.fSqlCommand.Connection.Close();
                }
            }
            this.EventoDespuesDelCommit();
        }

        public void Rollback()
        {
            this.EventoAntesDelRollback();
            if (this.fSqlCommand != null)
            {
                if (this.Transaccional())
                {
                    this.fSqlCommand.Transaction.Rollback();
                }
            }
            this.EventoDespuesDelRollback();
        }

        #endregion

        #region Eventos Publicados

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public event TransaccionEventoEventHandler AntesDelCommit;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public event TransaccionEventoEventHandler DespuesDelCommit;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public event TransaccionEventoEventHandler AntesDelRollback;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public event TransaccionEventoEventHandler DespuesDelRollback;

        #endregion

    }

    public delegate void TransaccionEventoEventHandler();

}
